package net.entelijan.cobean.examples.data.literature.wrapper;

import java.util.ArrayList;
import java.util.List;

import net.entelijan.cobean.data.literature.ILitService;
import net.entelijan.cobean.data.literature.LitAuthor;
import net.entelijan.cobean.data.literature.LitBook;
import net.entelijan.cobean.data.literature.LitBookSearchItem;
import net.entelijan.cobean.data.literature.OrderAttribute;
import net.entelijan.cobean.examples.data.literature.endpoint.WsLitService;

import org.dozer.Mapper;

public class WrappedService implements ILitService {

	private WsLitService wsService;

	private Mapper mapper;

	public WrappedService(WsLitService wsService, Mapper mapper) {
		super();
		this.wsService = wsService;
		this.mapper = mapper;
	}

	public void addBookToAuthor(LitAuthor author, LitBook book) {
		this.wsService.addBookToAuthor(copyProperties(author),
				copyProperties(book));
	}

	public List<LitBook> findBooks(LitBookSearchItem searchItem) {
		List<net.entelijan.cobean.examples.data.literature.endpoint.LitBook> books = this.wsService
				.findBooks(copyProperties(searchItem));
		return copyBookList(books);
	}

	public long getBookCount() {
		return this.wsService.getBookCount();
	}

	public List<LitAuthor> loadAllAuthors() {
		return copyAuthorList(wsService.loadAllAuthors());
	}

	public List<LitBook> loadAllBooks() {
		return copyBookList(wsService.loadAllBooks());
	}

	public LitAuthor loadAuthor(long id) {
		return copyProperties(wsService.loadAuthor(id));
	}

	public LitBook loadBook(long id) {
		return copyProperties(wsService.loadBook(id));
	}

	public List<LitBook> loadBooks(int fromIndex, int toIndex,
			List<OrderAttribute> order) {
		return copyBookList(wsService.loadBooks(fromIndex, toIndex,
				copyOrderList(order)));
	}

	public void removeBookFromAuthor(LitAuthor author, LitBook book) {
		wsService.removeBookFromAuthor(copyProperties(author),
				copyProperties(book));
	}

	public void saveAuthor(LitAuthor author) {
		wsService.saveAuthor(copyProperties(author));
	}

	public void saveBook(LitBook book) {
		wsService.saveBook(copyProperties(book));
	}

	@Override
	public void deleteAuthor(long id) {
		this.wsService.deleteAuthor(id);
	}

	@Override
	public void deleteBook(long id) {
		this.wsService.deleteBook(id);
	}

	private List<net.entelijan.cobean.examples.data.literature.endpoint.OrderAttribute> copyOrderList(
			List<OrderAttribute> order) {
		ArrayList<net.entelijan.cobean.examples.data.literature.endpoint.OrderAttribute> re = new ArrayList<net.entelijan.cobean.examples.data.literature.endpoint.OrderAttribute>();
		for (OrderAttribute a : order) {
			re.add(copyProperties(a));
		}
		return re;
	}

	private net.entelijan.cobean.examples.data.literature.endpoint.OrderAttribute copyProperties(
			OrderAttribute order) {
		return net.entelijan.cobean.examples.data.literature.endpoint.OrderAttribute
				.fromValue(order.name());
	}

	private List<LitBook> copyBookList(
			List<net.entelijan.cobean.examples.data.literature.endpoint.LitBook> books) {
		ArrayList<LitBook> re = new ArrayList<LitBook>();
		for (net.entelijan.cobean.examples.data.literature.endpoint.LitBook b : books) {
			re.add(copyProperties(b));
		}
		return re;
	}

	private List<LitAuthor> copyAuthorList(
			List<net.entelijan.cobean.examples.data.literature.endpoint.LitAuthor> authors) {
		ArrayList<LitAuthor> re = new ArrayList<LitAuthor>();
		for (net.entelijan.cobean.examples.data.literature.endpoint.LitAuthor a : authors) {
			re.add(copyProperties(a));
		}
		return re;
	}

	private LitBook copyProperties(
			net.entelijan.cobean.examples.data.literature.endpoint.LitBook book) {
		return mapper.map(book, LitBook.class);
	}

	private LitAuthor copyProperties(
			net.entelijan.cobean.examples.data.literature.endpoint.LitAuthor author) {
		return mapper.map(author, LitAuthor.class);
	}

	private net.entelijan.cobean.examples.data.literature.endpoint.LitBookSearchItem copyProperties(
			LitBookSearchItem searchItem) {
		return mapper
				.map(
						searchItem,
						net.entelijan.cobean.examples.data.literature.endpoint.LitBookSearchItem.class);
	}

	private net.entelijan.cobean.examples.data.literature.endpoint.LitAuthor copyProperties(
			LitAuthor author) {
		return mapper
				.map(
						author,
						net.entelijan.cobean.examples.data.literature.endpoint.LitAuthor.class);
	}

	private net.entelijan.cobean.examples.data.literature.endpoint.LitBook copyProperties(
			LitBook book) {
		return mapper
				.map(
						book,
						net.entelijan.cobean.examples.data.literature.endpoint.LitBook.class);
	}

}
